import type { GreasyForkPageTypes } from '../../../../../../../../../lib/page_handler/platform/greasyfork/types'
import type { GreasyForkUserType } from '../../module/storage_process/types'
import { IconService } from '../../../../../../../../../lib/icons'
import { ICON_IDS } from '../../../../../../../../../lib/icons/types/constants'
import { PageHandler } from '../../../../../../../../../lib/page_handler'
import { GreasyForkPageType } from '../../../../../../../../../lib/page_handler/platform/greasyfork/types'
import { ToolKit } from '../../../../../../../../../lib/utils/toolkit'
import { FEEDBACK_TAG_LABELS } from '../../../../../../../../../module/page_enhancer/interaction/platform/greasy_fork/feedback_mark'
import {
  getCurrentURL,
  HOSTNAME,
  logger,
  SignType,
  SUPPORTED_PLATFORMS,
} from '../../../../../../../../../types/constants'
import { GREASY_FORK_PAGE_ELEMENTS } from '../../../../../../../../../types/constants/personalization/greasy_fork'
import { StorageProcessor } from '../../module/storage_process'
import { getUserBadgeStyles } from './types'

export class GreasyFork {
  private readonly name: string = 'GreasyFork'
  private static instance: GreasyFork
  private scriptId: string = ''
  private storageProcessor: StorageProcessor = StorageProcessor.getInstance()
  private iconService: IconService = IconService.getInstance()
  readonly scriptStarClass: string = 'script-star'

  get pageType(): GreasyForkPageTypes {
    return PageHandler.getCurrentPageType() as GreasyForkPageTypes
  }

  private constructor() {
    if (!this.isGreasyForkPlatform())
      return

    this.init()
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): GreasyFork {
    if (!GreasyFork.instance) {
      GreasyFork.instance = new GreasyFork()
    }
    return GreasyFork.instance
  }

  private init(): void {
    this.scriptId = this.extractScriptIdFromUrl()
  }

  /**
   * 获取当前登录用户 id
   */
  getCurrentUserId(): string {
    const userUrl = this.getCurrentUserIndexLink()
    return this.extractUserIdFromUrl(userUrl)
  }

  /**
   * 获取当前登录用户名称
   */
  getCurrentUserName(): string {
    return $('#nav-user-info .user-profile-link a').text().trim() || ''
  }

  /**
   * 获取当前登录用户首页链接
   */
  getCurrentUserIndexLink(): string {
    return $('#nav-user-info .user-profile-link a').attr('href') || ''
  }

  /**
   * 获取登录类型
   */
  getSignType(): SignType {
    return $('#nav-user-info .sign-in-link')?.length ? SignType.SignIn : SignType.SignOut
  }

  /**
   * 获取退出链接
   */
  getSignOutLink(): string {
    return $('#nav-user-info .sign-out-link a').attr('href') || ''
  }

  /**
   * 获取登录链接
   */
  getSignInLink(): string {
    return $('#nav-user-info .sign-in-link a').attr('href') || ''
  }

  public getScriptListSelector(): string {
    switch (this.pageType) {
      case GreasyForkPageType.USER_PROFILE:
        return '#user-script-list li, #user-library-script-list li'
      case GreasyForkPageType.LIBRARIES:
      case GreasyForkPageType.SCRIPT_LIST:
        return GREASY_FORK_PAGE_ELEMENTS.RESULT_WRAPPER.selector
      default:
        return ''
    }
  }

  /**
   * 从 URL 中提取脚本 ID
   */
  private extractScriptIdFromUrl(): string {
    const match = getCurrentURL().match(/\/scripts\/(\d+)/)
    const scriptId = match ? match[1] : ''

    const supportedPages: GreasyForkPageTypes[] = [
      GreasyForkPageType.SCRIPT_INFO,
      GreasyForkPageType.SCRIPT_CODE,
      GreasyForkPageType.SCRIPT_VERSIONS,
      GreasyForkPageType.SCRIPT_FEEDBACK,
      GreasyForkPageType.SCRIPT_STATS,
      GreasyForkPageType.SCRIPT_DISCUSSION,
    ]

    if (scriptId.length === 0 && supportedPages.includes(this.pageType))
      logger.error(`[${this.name}] 从URL中提取脚本 ID 失败`)

    return scriptId
  }

  /**
   * 从 URL 中提取版本 ID
   */
  extractVersionIdFromUrl(versionUrl: string): string {
    return ToolKit.browser.url.getUrlParam(versionUrl, 'version') || ''
  }

  /**
   * 从 URL 中提取讨论 ID
   */
  extractDiscussionIdFromUrl(userUrl: string): string {
    const match = userUrl.match(/\/discussions\/(\d+)/)
    return match ? match[1] : ''
  }

  /**
   * 检查当前是否为 GreasyFork 平台
   */
  isGreasyForkPlatform(): boolean {
    return HOSTNAME === SUPPORTED_PLATFORMS.GREASY_FORK
  }

  /**
   * 获取脚本 ID
   */
  getScriptId(): string {
    return this.scriptId
  }

  /**
   * 格式化所有时间
   */
  formatAllTimes(containerSelector: string, timeSelector: string): void {
    const $container = $(containerSelector)
    const $timeElements = $container.find(timeSelector)

    if ($timeElements.length === 0)
      return

    $timeElements.each((_, element) => {
      this.formatSingleTime($(element))
    })
  }

  /**
   * 格式化单个时间
   */
  private formatSingleTime($element: JQuery) {
    const datetime = $element.attr('datetime')

    if (!datetime)
      return

    const localTime = new Date(datetime).toLocaleString()
    $(`<span class="gf-time-helper">（${localTime}）</span>`).insertAfter($element)
  }

  formatDeletedUser(selector: string): void {
    $(selector).each((_, element) => {
      const $element = $(element)
      const originalText = $element.text().trim()
      const userIdMatch = originalText.match(/^Deleted user (\d+)$/)

      if (userIdMatch) {
        const userId = userIdMatch[1] // 提取的数字ID

        // 创建容器
        const iconContainer = $(`
          <span class="deleted-user-wrapper" title="注销用户 (ID: ${userId})">
            ${this.iconService.api.icon.asSvg(ICON_IDS.auth.logout)}
          </span>
        `)

        // 替换原有内容
        $element.empty().append(iconContainer)
      }
    })
  }

  /**
   * 获取用户链接
   */
  getUserLink($element: JQuery, selector: string): JQuery {
    return !selector || selector.length === 0 ? $element : $element.find(selector)
  }

  /**
   * 处理用户标签
   */
  handleUserTag($element: JQuery, userLinkSelector: string, $targetElement?: JQuery): void {
    const $userLink = this.getUserLink($element, userLinkSelector)
    const userId = this.getUserId($userLink)
    const userTypes = this.storageProcessor.getUserType(userId)

    // 确定目标元素（使用传入的或默认为用户链接前）
    const $insertTarget = $targetElement || $userLink

    // 2. 移除旧用户铭牌
    $element.find('.user-badge').remove()

    // 3.添加新用户铭牌
    if (userTypes.length > 0) {
      const typeConfig = FEEDBACK_TAG_LABELS[userTypes[0] as GreasyForkUserType]
      const $badge = $(`
        <span class="user-badge ${userTypes[0]}" style="
          ${getUserBadgeStyles()}
          background: ${typeConfig.bgColor};
          color: ${typeConfig.textColor} !important;
          margin: 4px !important;"
        >
          ${typeConfig.icon} ${typeConfig.label}
        </span>
      `)

      // 根据是否有目标元素决定插入方式
      if ($targetElement) {
        $insertTarget.append($badge)
      }
      else {
        $insertTarget.after($badge)
      }
    }
  }

  /**
   * 获取用户 ID
   */
  getUserId($element: JQuery): string {
    const userUrl = $element.attr('href') || ''
    return this.extractUserIdFromUrl(userUrl)
  }

  /**
   * 从 URL 中提取用户 ID
   */
  extractUserIdFromUrl(url: string): string {
    if (!url || url.length === 0)
      return ''

    const match = url.match(/\/users\/(\d+)/)
    const userId = match ? match[1] : ''

    if (userId.length === 0)
      logger.error(`[${this.name}] 用户 ID 提取失败`)

    return userId
  }

  public static getCurrentScriptIdFromList($element: JQuery): string {
    const scriptId = $element.attr('data-script-id') || ''

    if (scriptId.length === 0)
      logger.error(`[${this.name}] 脚本 ID 提取失败`)

    return scriptId
  }
}
